﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EngineeringGraf;
using APMLogVisualizer;

namespace APMLogVisualizer
{
    public partial class DataGraph : Form
    {
        internal EngineeringGraph EG;
        private System.Drawing.Graphics GraphGraph = null;
        public DataGraph()
        {
            InitializeComponent();
            GraphGraph = CreateGraphics();

        }

        int tticks = 0;
        private void DataGraphTimer_Tick(object sender, EventArgs e)
        {
            if (tticks == 2)
            {
                EG = new EngineeringGraph(GraphGraph, this);
            }
            else if (tticks == 4)
            {
                EG.TitleString = "APM Visualizer. Click here for Help";
            }
            tticks++;
        }
        private int IndexIntoV = 0;
        internal int IndexInto
        {
            set
            {
                if (value != IndexIntoV)
                {
                    if(EG != null) EG.DrawTickMark(GraphGraph, value);
                }
                IndexIntoV = value;
            }
            get
            {
                return IndexIntoV;
            }
        }

        private void DataGraph_Paint(object sender, PaintEventArgs e)
        {
            GraphGraph = this.CreateGraphics();
            if (EG != null) EG.Paint(GraphGraph);
        }

        int LWidth, LHeight;
        private void DataGraph_Resize(object sender, EventArgs e)
        {
            if (this.Height < LHeight || this.Width < LWidth)
                this.Invalidate();
            LHeight = this.Height; LWidth = this.Width;
        }
        internal bool AddLine2Graph(String Name, String Description, float[] NewData, int length, float zero, float span, int dp)
        {
            float f = 0;
            if (length < 10) return false;

            for (int i = 0; i < GConst.MaxLines; i++)
            {
                if (EG.PData[i].PointName == Name)
                {
                    //if here, the point is already there.  We remove it.
                    EG.RemoveLineFromGraph(Name);
                    return false;
                }
            }

            float max = NewData[length / 2];
            float min = max;
            for (int i = 0; i < NewData.Length; i++)
            {
                f = NewData[i];
                if (f > max) max = f;
                if (f < min) min = f;
            }
            //  ReverseFloatArray(NewData);

            Color c = GetNextColor();
            if (max == 0 && min == 0) max = 0.001f;
            if (span != 0)
            {
                if (max > span) span = max; else max = span;
                if (min < zero) zero = min; else min = zero;
            }
            bool rv = false;
            if (EG != null && (max != min)) rv = EG.AddLineToGraph(Name, Description, c, 2.1f, max, min, 1.0, NewData, dp, length);
            return rv;
        }
        internal bool IsLabelOnGraph(Label l, String n)
        {
            if (EG == null) { l.ForeColor = Color.Green; return false; }
            for (int i = 0; i < GConst.MaxLines; i++)
            {
                if (EG.PData[i].PointName == n)
                {
                    l.ForeColor = Color.Red;
                    return true;
                }
            }
            l.ForeColor = Color.Green;
            return false;
        }
        void ReverseFloatArray(float[] f)
        {
            float[] fd = new float[f.Length];
            for (int i = 0; i < f.Length; i++)
            {
                fd[f.Length-i-1] = f[i];
            }
            for (int i = 0; i < f.Length; i++)
            {
                f[i] = fd[i];
            }
        }
        Color[] ca = new Color[8];
        int ColorIndex = -1;
        Color GetNextColor()
        {
            if (ColorIndex < 0)
            {
                for (int i = 0; i < 8; i++)
                {
                    ca[i] = new Color();
                }
                ca[0] = Color.Red;
                ca[1] = Color.Green;
                ca[2] = Color.Magenta;
                ca[3] = Color.MediumSeaGreen;
                ca[4] = Color.Yellow;
                ca[5] = Color.Turquoise;
                ca[6] = Color.LightSalmon;
                ca[7] = Color.LightGoldenrodYellow;
                ColorIndex = 7;
            }
            if (++ColorIndex > 7) ColorIndex = 0;
            return ca[ColorIndex];
        }
        private void DataGraph_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            Visible = false;
        }
        internal void ClearGraph()
        {
            if (EG == null) return;
            EG.ClearGraph();
        }
        //Mouse Stuff
        private void DataGraph_MouseDown(object sender, MouseEventArgs e)
        {
            EG.MouseDown(e);
        }
        private void DataGraph_MouseUp(object sender, MouseEventArgs e)
        {
            if (EG.ClickOnGraphTitle(e.X, e.Y))
            {
                BigMessages bm = new BigMessages();
                bm.TBMessage.Text = @"Graph Helpful Hints: 

Click and Drag to zoom into the graph. Right click on the graph to UnZoom.  

If the mouse pointer is NOT in the graph data area:
The numbers at the right show the Average value for the current on screen portion of the data, 

If the mouse pointer IS in the graph data area:
The numbers at the right show the current value, where the mouse pointer is.  
There is a vertical bar in the graph where the mouse pointer (and the data that's displayed) is.

The scale on the left (the vertical scale) will reflect the last data line that you add.  
If you want to change the vertical scale to match another data line, left click on the data line label 
at the right.

To Delete a point from the graph, right click on the Point Name, on the right side of the graph.

The scale ""engineering units"" are automatic, based on the greatest and least values for that data line.
Sometimes the ""Engineering units"" are constants, for instance the motor outputs are 1000 to 2000, 
however, if the data happens to go over the  ""engineering units"" that are constants, the 
""Engineering Units"" will be changed to the higher (or lower) value.

If you're 'Playing' or sliding the slider for a LOG file, then there is a vertical bar, where the 
current play Log Line pointer is.

A REALLY Cool feature starting with version 1.13 is the main window display is updated
with the location that the slider in the graph is on!  Wow, all the digital readouts
in the main window are updated where you have the slider in a graph!  Now that is
COOL!

";

                bm.Text = "Graph Helpful Hints";

                bm.ShowDialog();
                return;
            }

            EG.MouseUp(e);
        }

        private void DataGraph_MouseClick(object sender, MouseEventArgs e)
        {
        }

        private void DataGraph_MouseMove(object sender, MouseEventArgs e)
        {
           EG.MouseMove(GraphGraph, e);
        }
    }
}
